package com.da.auth.security.service;

import com.da.auth.entity.DailyRole;
import com.da.auth.entity.DailyUserRoles;
import com.da.auth.entity.DailyUsers;

import com.da.auth.entity.UserInfo;
import com.da.auth.entity.constant.DailyAuthConstant;
import com.da.auth.entity.dto.DailyUsersDTO;
import com.da.auth.entity.vo.UserDetailsVO;
import com.da.auth.mapper.DailyRoleMapper;
import com.da.auth.mapper.DailyUserRolesMapper;
import com.da.auth.mapper.DailyUsersMapper;

import com.da.auth.redis.RedisCache;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author: hyacinth
 * @CreateTime: 2025-02-10
 * @Version: 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final RedisCache redisCache;
    @Resource
    private DailyUsersMapper dailyUsersMapper;

    private final DailyRoleMapper dailyRoleMapper;

    private final DailyUserRolesMapper dailyUserRolesMapper;


    /**
     * 根据用户名查询用户信息
     *
     * @param username 用户名
     * @return 用户信息
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = null;
        UserDetailsVO userDetailsVO = new UserDetailsVO();
        if (username.isEmpty()) {
            throw new InternalAuthenticationServiceException("用户名称不能为空");
        }
        log.info("redisKey:{}", DailyAuthConstant.USER_PREFIX + username);
        Object userObject = redisCache.getCacheObject(DailyAuthConstant.USER_PREFIX + username);
        if (Objects.isNull(userObject)) {
            DailyUsers dailyUsers = dailyUsersMapper.queryByUserName(username);
            if (Objects.isNull(dailyUsers)) {
                throw new RuntimeException("用户不存在");
            }
            List<DailyUserRoles> dailyUserRoles = dailyUserRolesMapper.queryListByUserId(dailyUsers.getId());
            Collection<String> roles = new LinkedList<>();
            for (DailyUserRoles dailyUserRole : dailyUserRoles) {
                DailyRole dailyRole = dailyRoleMapper.queryById(dailyUserRole.getRoleId());
                roles.add(dailyRole.getRoleName());
            }
            userInfo = new UserInfo(dailyUsers.getId(), dailyUsers.getUsername(), dailyUsers.getPassword(), roles);

            // 组装储存redis的用户数据
            userDetailsVO.setId(dailyUsers.getId());
            userDetailsVO.setUsername(dailyUsers.getUsername());
            userDetailsVO.setPassword(dailyUsers.getPassword());
            userDetailsVO.setRoles(roles);
            String userKey = DailyAuthConstant.USER_PREFIX + username;
            redisCache.setCacheObject(userKey, userDetailsVO, DailyAuthConstant.TOKEN_EXPIRATION, TimeUnit.MINUTES);
        } else {
            log.info("redis中获取用户信息");
            if (userObject instanceof UserDetailsVO) {
                userDetailsVO = (UserDetailsVO) userObject;
                userInfo = new UserInfo(userDetailsVO.getId(), userDetailsVO.getUsername(), userDetailsVO.getPassword(), userDetailsVO.getRoles());
            }
        }
        //将信息添加到User也可以说是UserDetails 对象中
        return userInfo;
    }

}
